import * as AISKey from './ais-key.js'

export class VueAIS {
  constructor () {
    // 是否处于开机状态
    this.poweron = false
    this.showBrill = false
    this._pageLayers = ['']
    this._currentPage = ''
    // page--->vm映射
    this._vms = {}
    this.router = undefined
  }

  toString () {
    return 'AIS{ poweron:' + this.poweron +
      ' showBrill:' + this.showBrill +
      ' currentPage:' + this.currentPage +
      ' }'
  }

  set currentPage (val) {
    this._pageLayers[this._pageLayers.length - 1] = val
    this._currentPage = val
    console.log('set currentPage: ' + val)
  }

  get currentPage () {
    return this._currentPage
  }

  pushPage (page) {
    this._pageLayers.push(page)
    this._currentPage = page
  }

  popPage () {
    if (this._pageLayers.length <= 1) {
      console.error('cannot pop page, pageLayers:' + this._pageLayers)
    } else {
      this._pageLayers.pop()
      this._currentPage = this._pageLayers[this._pageLayers.length - 1]
    }
  }

  pageStackIncludes (page) {
    return this._pageLayers.indexOf(page) !== -1
  }

  _triggeredKey (evt, funcname) {
    let page = this.currentPage
    if (page) {
      let vm = this._vms[page]
      if (vm === undefined) {
        let a = page.split('/')
        for (var i = a.length - 1; i >= 0; i--) {
          a[i] = '*'
          vm = this._vms[a.join('/')]
          if (vm !== undefined) {
            break
          }
        }
      }
      if (!vm) {
        console.log('cannot find ' + page + ' ---> vue instance')
        return
      }
      let _vm = evt.vm
      evt.vm = vm
      let handler = vm.$options[funcname]
      if (handler) {
        // console.debug('call key: ' + keyname + ' holdon:' + evt.holdon)
        if (handler.length >= 1) {
          handler.call(vm, evt)
        } else {
          handler.call(vm)
        }
      }

      if (evt.continue && evt.anykey) {
        funcname = AISKey.ANYKEY
        if (evt.holdon) {
          funcname += 'holdon'
        }
        let handler = vm.$options[funcname]
        if (handler) {
          handler.call(vm, evt)
        }
      }
      evt.vm = _vm
    }
  }

  holdon (evt) {
    let funcname = AISKey.KEYMAP[evt.keyname] + 'holdon'
    this._triggeredKey(evt, funcname)

    let counter = 0
    while (evt.rehandle === true) {
      evt.rehandle = false
      this._triggeredKey(evt, funcname)
      counter++
      if (counter >= 10) {
        console.warn('holdon rehandle more than 10, stop it')
        break
      }
    }
  }

  click (evt) {
    let funcname = AISKey.KEYMAP[evt.keyname]
    this._triggeredKey(evt, funcname)
    let counter = 0
    while (evt.rehandle === true) {
      evt.rehandle = false
      this._triggeredKey(evt, funcname)
      counter++
      if (counter >= 10) {
        console.warn('holdon rehandle more than 10, stop it')
        break
      }
    }
  }

  dbclick (evt) {
    let funcname = AISKey.KEYMAP[evt.keyname] + 'dblclick'
    this._triggeredKey(evt, funcname)
  }

  addvm (page, vm) {
    this._vms[page] = vm
    console.debug('SpeedLog addvm { page: ' + page + ' }')
  }

  removevm (page) {
    delete this._vms[page]
    console.debug('SpeedLog removevm { page: ' + page + ' }')
  }

  routeTo (page) {
    this.router.go('/' + page)
    this.currentPage = page
  }

  clearMenu () {
    let evt = {
      ais: this,
      keyname: 'AISLeft',
      continue: true,
      anykey: true,
      currentPage: this.currentPage,
      app: this,
      vm: this,
      rehandle: true
    }
    for (let i = this._pageLayers.length - 1; i >= 0; i--) {
      this.currentPage = this._pageLayers[i]
      evt.rehandle = true
      this._triggeredKey(evt, 'AISLeft')
    }
  }
}

let _ais = new VueAIS()
window.$ais = _ais
export const ais = _ais

function applyOverride (Vue) {
  const {
    defineReactive
  } = Vue.util

  // override Vue's init and destroy process to keep track of router instances
  const _init = Vue.prototype._init

  Vue.prototype._init = function (options = {}) {
    options.init = options.init
      ? [aisInit].concat(options.init)
      : aisInit

    this.$ais = _ais
    defineReactive(this, '$ais', _ais)

    _init.call(this, options)
  }

  function aisInit () {
  }
}

VueAIS.installed = false
VueAIS.install = function (externalVue) {
  /* istanbul ignore if */
  if (VueAIS.installed) {
    console.warn('already installed.')
    return
  }
  applyOverride(externalVue)
  VueAIS.installed = true
}

